/*  Mash-code. Mash Arts & Métiers Angers embedded software
 *  Copyright (C) 2014  Mash Arts & Métiers Angers
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************
#include <xc.h>
#include <stdint.h>
#include <p33FJ128MC802.h>
#include "pwm_device.h"

/*****************************************************************************
// *****************************************************************************
// Section: File Scope or Global Constants
// *****************************************************************************
// *****************************************************************************/

uint8_t status;

// *****************************************************************************
// Section: Function definition
// *****************************************************************************
// *****************************************************************************

void initPWM( void )
{
    /* PWM time based operates in Free mode */
    P1TCONbits.PTMOD = 0b00;

    /* PWM time base input clock periode si Tcy (1:1 prescale) */
    /* PWM time base output scale is 1:1 */
    P1TCONbits.PTCKPS = 0b00;
    P1TCONbits.PTOPS = 0b00;

    /* Choose PWM time period based on input clock selected */
    /* P1TPER = (Fcy / (Fpwm * Prescal))-1 */
    /* PWM switching frequency is 8 kHz */
    /* FCY is 50 MHz */
    P1TPER = PWM_PERIODE;

    /* PWM I/O pairs 1 to 3 are in complementary mode */
    /* PWM pins are enabled for PWM output */
    PWM1CON1bits.PMOD1 = 0;
    PWM1CON1bits.PMOD2 = 0;
    PWM1CON1bits.PMOD3 = 0;
    PWM1CON1bits.PEN1H = 1;
    PWM1CON1bits.PEN2H = 1;
    PWM1CON1bits.PEN3H = 1;
    PWM1CON1bits.PEN1L = 1;
    PWM1CON1bits.PEN2L = 1;
    PWM1CON1bits.PEN3L = 1;

    /* Immediate update of PWM enabled */
    PWM1CON2bits.IUE = 1;
    PWM1CON2bits.UDIS = 0;

    /* Clock period for Dead Time Unit A is TcY */
    /* Clock period for Dead Time Unit B is TcY */
    P1DTCON1bits.DTAPS = 0b00;
    P1DTCON1bits.DTBPS = 0b00;

    /* Dead time value for Dead Time Unit A */
    /* Dead time value for Dead Time Unit B */
    P1DTCON1bits.DTA = 10;
    P1DTCON1bits.DTB = 20;

    /* Dead Time Unit selection for PWM signals */
    /* Dead Time Unit A selected for PWM active transitions */
    /* Dead Time Unit B selected for PWM inactive transitions */
    P1DTCON2bits.DTS3A = 0;
    P1DTCON2bits.DTS2A = 0;
    P1DTCON2bits.DTS1A = 0;
    P1DTCON2bits.DTS3I = 1;
    P1DTCON2bits.DTS2I = 1;
    P1DTCON2bits.DTS1I = 1;

    /* PWM I/O pin controlled by PWM Generator */
    P1OVDCONbits.POVD3H = 1;
    P1OVDCONbits.POVD2H = 1;
    P1OVDCONbits.POVD1H = 1;
    P1OVDCONbits.POVD3L = 1;
    P1OVDCONbits.POVD2L = 1;
    P1OVDCONbits.POVD1L = 1;

    P1TCONbits.PTEN = 1;

    PWM_disable();
}

void PWM_disable( void )
{
    status = 0;

    /* Override control register configuration */
    /* Output on the PWMxHy and PWMxLy I/O pins are controlled by the */
    /* corresponding POUTx bits in the PxOVDCON register */
    P1OVDCONbits.POVD3H = 0;
    P1OVDCONbits.POVD2H = 0;
    P1OVDCONbits.POVD1H = 0;
    P1OVDCONbits.POVD3L = 0;
    P1OVDCONbits.POVD2L = 0;
    P1OVDCONbits.POVD1L = 0;
    
    /* PWM I/O pins are driven to active state by setting the corresponding bit */
    P1OVDCONbits.POUT3H = 0;
    P1OVDCONbits.POUT2H = 0;
    P1OVDCONbits.POUT1H = 0;
    P1OVDCONbits.POUT3L = 1;
    P1OVDCONbits.POUT2L = 1;
    P1OVDCONbits.POUT1L = 1;
}

void PWM_enable( void )
{
    status = 1;

    P1OVDCONbits.POVD3H = 1;
    P1OVDCONbits.POVD2H = 1;
    P1OVDCONbits.POVD1H = 1;
    P1OVDCONbits.POVD3L = 1;
    P1OVDCONbits.POVD2L = 1;
    P1OVDCONbits.POVD1L = 1;
}

void PWM_setRaw( struct struct_raw raw )
{
    P1DC1 = (raw.a>>8) * PWM_PDIV;
    P1DC2 = (raw.b>>8) * PWM_PDIV;
    P1DC3 = (raw.c>>8) * PWM_PDIV;
}

uint8_t PWM_getStatus( void )
{
    return status;
}

/*******************************************************************************
 End of File
*/

